package com.shuzi.MediaShare.download;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.text.TextUtils;
import android.widget.Toast;

import com.shuzi.MediaShare.utils.Logger;
import com.shuzi.MediaShare.utils.Util;

/**
 * 下载管理器
 * 
 * @author lung 下午10:21:35 2013
 */
public class DownloadManager
{
	private static DownloadManager instance;

	private Context context;

	/** 是否有网络 */
	public boolean isNetWorksAvailable = true;

	public ExecutorService theThreadPool;

	private HashMap<String, DownloadInfo> allDownloadMap = null;

	private HashMap<String, DownloadTask> allDownloadTaskMap = null;

	private HashMap<String, Future<?>> allDownloadFutureMap = null;

	private List<DownloadListener> allDownloadListeners = null;

	private List<DownloadInfo> allDownloadInfosLists = null;

	private String basePath = "";

	private Logger logger;

	public String getBasePath()
	{
		return basePath;
	}

	public DownloadManager()
	{
		theThreadPool = Executors.newFixedThreadPool(2);
		allDownloadListeners = new ArrayList<DownloadListener>();
		allDownloadMap = new HashMap<String, DownloadInfo>();
		allDownloadTaskMap = new HashMap<String, DownloadTask>();
		allDownloadFutureMap = new HashMap<String, Future<?>>();
		allDownloadInfosLists = new ArrayList<DownloadInfo>();
		logger = Logger.getLogger();
	}

	/**
	 * 获取单实例
	 * 
	 * @return
	 */
	public static DownloadManager getInstace()
	{
		if (instance == null)
		{
			instance = new DownloadManager();
		}
		return instance;
	}

	/**
	 * 初始化
	 * 
	 * @param context
	 */
	public void init(Context context)
	{
		this.context = context;
		registerDateTransReceiver();

		makeDir();
	}

	/**
	 * 显示toast信息
	 */
	public void showToast(final String infoTest)
	{
		Toast.makeText(context, infoTest, Toast.LENGTH_SHORT).show();
	}

	/**
	 * 创建文件夹
	 */
	private void makeDir()
	{
		String sdPath = Util.getSDPath();
		if (sdPath != null)
		{
			basePath = sdPath + "/MediaPlayer/download/";

		} else
		{
			basePath = context.getCacheDir().getPath()
					+ "/MediaPlayer/download/";
		}
		File file = new File(basePath);
		if (!file.exists())
		{
			file.mkdirs();
		}

	}

	/**
	 * 注册下载监听器
	 * 
	 * @param listener
	 */
	public synchronized boolean registerDownloadListener(
			DownloadListener listener)
	{
		if (allDownloadListeners != null
				&& !allDownloadListeners.contains(listener))
		{
			return allDownloadListeners.add(listener);
		}
		return false;
	}

	public synchronized boolean unRegisterDownloadListener(
			DownloadListener listener)
	{
		if (allDownloadListeners != null)
		{
			return allDownloadListeners.remove(listener);
		}
		return false;
	}

	/**
	 * 得到所有的下载任务
	 * 
	 * @return
	 */
	public List<DownloadInfo> getAllDownloadInfos()
	{
		if (allDownloadInfosLists != null)
		{
			return allDownloadInfosLists;
		}
		return null;

	}

	/**
	 * 注册监听网络变化的广播
	 */

	public void registerDateTransReceiver()
	{
		IntentFilter filter = new IntentFilter();
		CheckNetWorkBroadCast checkNetWorkBroadCast = new CheckNetWorkBroadCast();
		filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
		filter.setPriority(1000);
		context.registerReceiver(checkNetWorkBroadCast, filter);
	}

	private class CheckNetWorkBroadCast extends BroadcastReceiver
	{

		@Override
		public void onReceive(Context context, Intent intent)
		{
			String action = intent.getAction();

			if (TextUtils
					.equals(action, "android.net.conn.CONNECTIVITY_CHANGE"))
			{// 网络变化的时候会发送通知
				ConnectivityManager cManager = (ConnectivityManager) context
						.getSystemService(Context.CONNECTIVITY_SERVICE);
				NetworkInfo info = cManager.getActiveNetworkInfo();
				if (info != null && info.isAvailable())
				{
					// 能联网
					isNetWorksAvailable = true;
				} else
				{
					isNetWorksAvailable = false;
				}
			}
		}
	}

	/**
	 * 添加下载任务下载
	 * 
	 * @param downloadInfo
	 * @return
	 */
	public synchronized boolean addDownloadInfoAndStart(
			DownloadInfo downloadInfo)
	{
		boolean isSuccess = false;

		// 判斷是否有sd卡
		if (Util.getSDPath() == null)
		{
			Toast.makeText(context, "sd卡不存在，无法下载", Toast.LENGTH_SHORT).show();
			return false;
		}

		if (Util.getSDFreeSize() < 1048576)
		{
			Toast.makeText(context, "sd卡剩余空间不足，无法下载", Toast.LENGTH_SHORT)
					.show();
			return false;
		}

		if (allDownloadMap.containsKey(downloadInfo.getKey()))
		{
			Toast.makeText(context, "任务已经在下载列表，请查看!", Toast.LENGTH_SHORT)
					.show();
			return false;
		}

		try
		{
			// 创建下载任务
			DownloadTask task = new DownloadTask(downloadInfo, this);
			Future<?> f = theThreadPool.submit(task);
			allDownloadMap.put(downloadInfo.getKey(), downloadInfo);
			allDownloadTaskMap.put(downloadInfo.getKey(), task);
			allDownloadFutureMap.put(downloadInfo.getKey(), f);
			allDownloadInfosLists.add(downloadInfo);
			isSuccess = true;
			Toast.makeText(context, "添加下载任务成功", Toast.LENGTH_SHORT).show();
			notifyDownloadDeleteEvent(DownloadInfo.STATE_WAIT, downloadInfo);
		} catch (Exception e)
		{
			isSuccess = false;
		}

		return isSuccess;
	}

	/**
	 * 重新开始下载任务
	 * 
	 * @param downloadInfo
	 * @return
	 */
	public synchronized boolean restartDownloadInfo(DownloadInfo downloadInfo)
	{

		boolean isSuccess = false;

		// 判斷是否有sd卡
		if (Util.getSDPath() == null)
		{
			Toast.makeText(context, "sd卡不存在，无法下载", Toast.LENGTH_SHORT).show();
			return false;
		}

		if (Util.getSDFreeSize() < 1048576)
		{
			Toast.makeText(context, "sd卡剩余空间不足，无法下载", Toast.LENGTH_SHORT)
					.show();
			return false;
		}

		try
		{
			downloadInfo.reset();
			// 创建下载任务
			DownloadTask task = new DownloadTask(downloadInfo, this);
			Future<?> f = theThreadPool.submit(task);
			// allDownloadMap.put(downloadInfo.getKey(), downloadInfo);
			allDownloadTaskMap.put(downloadInfo.getKey(), task);
			allDownloadFutureMap.put(downloadInfo.getKey(), f);
			// allDownloadInfosLists.add(downloadInfo);
			isSuccess = true;
			// Toast.makeText(context, "添加下载任务成功", Toast.LENGTH_SHORT).show();
			// notifyDownloadStateEvent(DownloadInfo.STATE_WAIT, downloadInfo);
			notifyDownloadDeleteEvent(DownloadInfo.STATE_WAIT, downloadInfo);
		} catch (Exception e)
		{
			isSuccess = false;
		}

		return isSuccess;
	}

	/**
	 * 暂停下载任务
	 * 
	 * @param downloadInfo
	 */
	public synchronized void stopDownloadInfo(DownloadInfo downloadInfo)
	{
		if (downloadInfo == null)
		{
			return;
		} else if (downloadInfo.getState() != DownloadInfo.STATE_DOWNLOADING)
		{
			return;
		}
		downloadInfo.setState(DownloadInfo.STATE_STOP);
		notifyDownloadStateEvent(DownloadInfo.STATE_STOP, downloadInfo);
		Future<?> future = allDownloadFutureMap.get(downloadInfo.getKey());
		DownloadTask task = allDownloadTaskMap.get(downloadInfo.getKey());
		if (task != null)
		{
			task.setCancel(true);
		}
		if (future != null)
		{
			future.cancel(false);
			allDownloadFutureMap.remove(downloadInfo.getKey());
			allDownloadTaskMap.remove(downloadInfo.getKey());
		}

		showToast(downloadInfo.getName() + "已暂停");

	}

	/**
	 * 删除下载任务
	 * 
	 * @param downloadInfo
	 */
	public synchronized boolean deleteDownloadInfo(DownloadInfo downloadInfo)
	{
		if (downloadInfo == null)
		{
			return false;
		}

		Future<?> future = allDownloadFutureMap.get(downloadInfo.getKey());
		DownloadTask task = allDownloadTaskMap.get(downloadInfo.getKey());
		if (task != null)
		{
			task.setCancel(true);
		}
		if (future != null)
		{
			future.cancel(false);
			allDownloadFutureMap.remove(downloadInfo.getKey());
		}
		allDownloadTaskMap.remove(downloadInfo.getKey());
		allDownloadInfosLists.remove(downloadInfo);
		allDownloadMap.remove(downloadInfo.getKey());
		notifyDownloadDeleteEvent(DownloadInfo.STATE_STOP, downloadInfo);
		// showToast(downloadInfo.getName() + "已暂停");
		return true;

	}

	/**
	 * 通知下载进度
	 * 
	 * @param percent
	 * @param info
	 */
	synchronized void notifyDownloadProgressEvent(int percent, DownloadInfo info)
	{
		logger.v("download", info.getName() + "---percent = " + percent);
		for (DownloadListener listener : allDownloadListeners)
		{
			listener.onProgress(percent, info);
		}
	}

	/**
	 * 通知下载状态
	 * 
	 * @param percent
	 * @param info
	 */
	synchronized void notifyDownloadStateEvent(int state, DownloadInfo info)
	{
		logger.v("download", info.getName() + "---state = " + state);
		for (DownloadListener listener : allDownloadListeners)
		{
			listener.onStateChange(state, info);
		}
	}

	/**
	 * 通知下载状态删除
	 * 
	 * @param percent
	 * @param info
	 */
	synchronized void notifyDownloadDeleteEvent(int state, DownloadInfo info)
	{
		logger.v("download", info.getName() + "---state = " + state);
		for (DownloadListener listener : allDownloadListeners)
		{
			listener.onTaskCountChanged(state, info);
		}
	}

	/**
	 * 得到具体的下载任务
	 * 
	 * @param key
	 * @return
	 */
	public DownloadInfo getDownloadInfo(String key)
	{
		if (allDownloadMap != null && allDownloadMap.size() != 0)
		{
			return allDownloadMap.get(key);
		}
		return null;
	}
}
